#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "commtraff.h"
#include "commtraff_info_print.h"
#include "commtraff_stress_test.h"
#include "commtraff_tool_com.h"
#include "commtraff_mock.h"

#define CMD_DESC_INFO_LEN 50
#define HOURS_PER_DAY 24
#define SECONDS_PER_HOUR 3600
#define TIME_FORMAT_STRING "%d-%d-%d %d:%d:%d"
#define TIME_FORMAT_EXAMPLE "2023-12-25 14:30:00"
#define MIN_YEAR 1900
#define MAX_YEAR 9999
#define MIN_MONTH 1
#define MAX_MONTH 12
#define MIN_DAY 1
#define MAX_DAY 31
#define MIN_HOUR 0
#define MAX_HOUR 23
#define MIN_MINUTE 0
#define MAX_MINUTE 59
#define MIN_SECOND 0
#define MAX_SECOND 59

// 定义流量类型名称数组，与 TraffType 枚举对应
const char *traffic_type_names[] = {
        "Link Layer Data",
        "Transport Layer Data",
        "Session Layer Data",
        "RPC Layer Data",
        "WPA Layer Data",
        "HISYSEVENT Data"
};

typedef void(*CmdFunc)(void);
typedef struct {
    char desc[CMD_DESC_INFO_LEN];
    CmdFunc func;
} CmdNode;

// 函数声明
static void HandleSingleInsert(void);
static void CommTraffNumsQuery(void);
static void QueryCommTraffRecords(void);

// 分类菜单处理函数
static void HandleSingleInsertMenu(void);
static void HandleSingleQueryMenu(void);
static void HandleStressTestMenu(void);

// 主菜单选项数组（分类菜单）
static CmdNode g_mainMenuList[] = {
    {"Single Insert", HandleSingleInsertMenu},
    {"Single Query", HandleSingleQueryMenu},
    {"Stress Test", HandleStressTestMenu},
    {"Exit", NULL}
};

// 单次插入菜单
static CmdNode g_singleInsertMenu[] = {
    {"Single Traffic Type Insert", HandleSingleInsert},
    {"Back to Main Menu", NULL}
};

// 单次查询菜单
static CmdNode g_singleQueryMenu[] = {
    {"Query Traffic Records Count", CommTraffNumsQuery},
    {"Query Traffic Records Details", QueryCommTraffRecords},
    {"Back to Main Menu", NULL}
};

// 压力测试菜单
static CmdNode g_stressTestMenu[] = {
    {"Single Type Timed Insert", HandleSingleTypeTimed},
    {"Single Type Timed Query", HandleSingleTypeRead},
    {"Multi-Type Fixed/Random Insert", HandleBatchInsertion},
    {"Multi-Type Fixed/Random Query", HandleBatchRead},
    {"Advanced Multi-Type Insert", HandleAdvancedInsertion},
    {"Advanced Multi-Type Query", HandleAdvancedRead},
    {"Back to Main Menu", NULL}
};

// 菜单大小常量
static const unsigned int g_mainMenuNum = sizeof(g_mainMenuList) / sizeof(CmdNode);
static const unsigned int g_singleInsertMenuNum = sizeof(g_singleInsertMenu) / sizeof(CmdNode);
static const unsigned int g_singleQueryMenuNum = sizeof(g_singleQueryMenu) / sizeof(CmdNode);
static const unsigned int g_stressTestMenuNum = sizeof(g_stressTestMenu) / sizeof(CmdNode);

// 通用菜单打印函数
static void PrintGenericMenu(const char* title, CmdNode menu[], unsigned int menuNum, const char* backOption) {
    PrintTooLName(title);
    for (unsigned int i = 0; i < menuNum - 1; i++) {  // 不打印最后一个选项（Back/Exit）
        printf("| %d - %-*s     |\r\n", i + 1, TOOL_LIST_WIDTH - 11, menu[i].desc);
    }
    printf("| %d - %-*s     |\r\n", 0, TOOL_LIST_WIDTH - 11, backOption);
    PrintLine(TOOL_LIST_WIDTH);
    printf("\n");
    printf("Enter your choice: ");
    fflush(stdout);
}

// 打印功能分类说明
static void PrintCategoryHelp() {
    printf("\n");
    PrintTooLName("COMMTRAFF TOOL V2.0 - Category Guide");
    printf("| %-20s | %-30s |\n", "Category", "Description");
    PrintLine(TOOL_LIST_WIDTH);
    printf("| %-20s | %-30s |\n", "Single Insert", "Insert one traffic record");
    printf("| %-20s | %-30s |\n", "Single Query", "Query existing records");
    printf("| %-20s | %-30s |\n", "Stress Test", "High-frequency operations");
    PrintLine(TOOL_LIST_WIDTH);
    printf("\nDetailed Functions:\n");
    printf("1. Single Insert:\n");
    printf("   - Insert one traffic record of selected type\n");
    printf("   - Simple one-time operation\n");
    printf("\n2. Single Query:\n");
    printf("   - Query traffic records count\n");
    printf("   - Query detailed traffic records\n");
    printf("\n3. Stress Test:\n");
    printf("   - Single type timed insert (fixed/random intervals)\n");
    printf("   - Single type timed query (fixed/random intervals)\n");
    printf("   - Multi-type insert (fixed/random intervals)\n");
    printf("   - Multi-type query (fixed/random intervals)\n");
    printf("   - Advanced multi-type insert (custom intervals)\n");
    printf("   - Advanced multi-type query (custom intervals)\n");
    printf("\nPress Enter to continue...");
    getchar();
}

// 打印主菜单
static void PrintMenu() {
    PrintGenericMenu("COMMTRAFF TOOL V2.0 - Main Menu", g_mainMenuList, g_mainMenuNum, "Exit");
    printf("\n");
    printf("Categories:\n");
    printf("1. Single Insert   - Insert one traffic record\n");
    printf("2. Single Query    - Query existing records\n");
    printf("3. Stress Test     - High-frequency operations\n");
    printf("\nEnter your choice (0-3), or 'h' for detailed help: ");
    fflush(stdout);
}

// 打印用于模拟的流量类型
void PrintTraffTypes() {
    PrintTooLName("Select traffic type to mock");
    for (int i = 0; i < sizeof(traffic_type_names) / sizeof(traffic_type_names[0]); i++) {
        printf("| %d - %-*s     |\r\n", i + 1, TOOL_LIST_WIDTH - 11, traffic_type_names[i]);
    }
    printf("| %d - %-*s     |\r\n", 0, TOOL_LIST_WIDTH - 11, "Back to main menu");
    PrintLine(TOOL_LIST_WIDTH);
    printf("\n");
    printf("Enter traffic type: ");
    fflush(stdout);
}


// 执行指定类型的Mock插入
static void ExecuteSingleMockInsertion(int traff_type) {
    switch (traff_type) {
        case 1:  // LINK_LAYER_DATA
            MockLinkTraff();
            break;
        case 2:  // TRANSPORT_LAYER_DATA
            MockTransportTraff();
            break;
        case 3:  // SESSION_LAYER_DATA
            MockSessionTraff();
            break;
        case 4:  // RPC_LAYER_DATA
            MockRpcTraff();
            break;
        case 5:  // WPA_LAYER_DATA
            MockWpaTraff();
            break;
        case 6:  // HISYSEVENT_DATA
            MockHisyseventTraff();
            break;
        default:
            printf("Invalid traffic type!\n");
            break;
    }
}

// 处理单次插入（基础操作）
static void HandleSingleInsert() {
    while (1) {
        // 选择流量类型
        PrintTraffTypes();
        int traff_type = SafeReadInt(sizeof(traffic_type_names) / sizeof(traffic_type_names[0]));
        if (traff_type == 0) {
            break; // 返回主菜单
        }
        
        // 执行单次插入
        ExecuteSingleMockInsertion(traff_type);
        printf("Successfully inserted one %s record.\n", traffic_type_names[traff_type - 1]);
        printf("Press Enter to continue...");
        getchar();
    }
}

// 回调函数，处理查询结果
static void OnQuery(CommTraff* records, int32_t nums) {
    printf("Received %d traffic records:\n", nums);
    int valid_records = 0;
    for (int i = 0; i < nums; i++) {
        // 检查记录中的数字字段是否全为0
        bool is_all_zero = false;
        CommTraff *record = &records[i];

        switch (record->traffType) {
            case LINK_LAYER_DATA: {
                LinkTraff *link = &record->data.linkTraff;
                is_all_zero = (link->txBytes == 0 && link->txPackets == 0 &&
                              link->rxBytes == 0 && link->rxPackets == 0 &&
                              link->rxErrPackets == 0 && link->txErrPackets == 0 &&
                              link->rxDropPackets == 0 && link->txDropPackets == 0);
                break;
            }
            case TRANSPORT_LAYER_DATA: {
                TransportTraff *transport = &record->data.transportTraff;
                is_all_zero = (transport->pid == 0 && transport->time == 0 &&
                        transport->sockId == 0 && transport->protocol == 0 &&
                        transport->sendBytes == 0 && transport->sendPacks == 0 &&
                        transport->recvBytes == 0 && transport->recvPacks == 0);
                break;
            }
            case SESSION_LAYER_DATA: {
                SessionTraff *session = &record->data.sessionTraff;
                is_all_zero = (session->pid == 0 && session->time == 0 &&
                        session->handle == 0 && session->channelId == 0 &&
                        session->connId == 0 && session->sessionId == 0 &&
                        session->sessionType == 0 &&
                        session->sendBytes == 0 && session->recvBytes == 0);
                break;
            }
            case RPC_LAYER_DATA: {
                RpcTraff *rpc = &record->data.rpcTraff;
                is_all_zero = (rpc->proxyHandle == 0 && rpc->stubHandle == 0 &&
                               rpc->sendDataLen == 0 && rpc->recvDataLen == 0 &&
                               rpc->recvDataSeq == 0 && rpc->sendDataSeq == 0);
                break;
            }
            case WPA_LAYER_DATA: {
                WpaTraff *wpa = &record->data.wpaTraff;
                is_all_zero = (wpa->signal == 0 && wpa->noise == 0 && wpa->snr == 0 &&
                               wpa->txrate == 0 && wpa->rxrate == 0 && wpa->realTxrate == 0 &&
                               wpa->realRxrate == 0 && wpa->txEfficiency == 0 && wpa->frequency == 0 &&
                               wpa->txPackets == 0 && wpa->rxPackets == 0 && wpa->chload == 0 &&
                               wpa->txBytes == 0 && wpa->rxBytes == 0 && wpa->txFailed == 0 &&
                               wpa->txRetries == 0);
                break;
            }
            case HISYSEVENT_DATA: {
                break;
            }
            default:
                is_all_zero = 1;
                break;
        }

        if (!is_all_zero) {
            CommTraffInfoPrint(&records[i]);
            fflush(stdout);
            valid_records++;
        }
    }
    printf("dump %d traffic records complete (filtered)\n", valid_records);
}

// 回调函数，处理查询完成事件
static void OnComplete(int32_t reason, int32_t total) {
    if (reason == COMMTRAFF_SUCCESS) {
        printf("Query completed successfully. Total records: %d\n", total);
    } else {
        printf("Query failed with reason code: %d\n", reason);
    }
}

// 通用子菜单处理函数
static void HandleSubMenu(const char* title, CmdNode menu[], unsigned int menuNum) {
    while (1) {
        PrintGenericMenu(title, menu, menuNum, "Back to Main Menu");
        
        int choice = SafeReadInt(menuNum - 1);  // 最大选项数(不包括Back)
        if (choice == 0) {
            break; // 返回主菜单
        } else if (choice >= 1 && choice < menuNum) {
            // 调用对应的函数
            if (menu[choice - 1].func != NULL) {
                menu[choice - 1].func();
            }
        } else {
            printf("Invalid choice! Please select from the available options.\n");
        }
    }
}

// 单次插入菜单处理
static void HandleSingleInsertMenu(void) {
    HandleSubMenu("Single Insert - Insert One Traffic Record", g_singleInsertMenu, g_singleInsertMenuNum);
}

// 单次查询菜单处理
static void HandleSingleQueryMenu(void) {
    HandleSubMenu("Single Query - Query Existing Records", g_singleQueryMenu, g_singleQueryMenuNum);
}

// 压力测试菜单处理
static void HandleStressTestMenu(void) {
    HandleSubMenu("Stress Test - High-Frequency Operations", g_stressTestMenu, g_stressTestMenuNum);
}

// 打印用于查询的流量类型
static void PrintTraffTypesForQuery() {
    PrintTooLName("Select traffic type to query");
    for (int i = 0; i < sizeof(traffic_type_names) / sizeof(traffic_type_names[0]); i++) {
        printf("| %d - %-*s     |\r\n", i + 1, TOOL_LIST_WIDTH - 11, traffic_type_names[i]);
    }
    printf("| %d - %-*s     |\r\n", 0, TOOL_LIST_WIDTH - 11, "Back to main menu");
    PrintLine(TOOL_LIST_WIDTH);
    printf("\n");
    printf("Enter traffic type: ");
}

// 打印时间范围
static void PrintTimeRanges() {
    PrintTooLName("Select time range");
    printf("| %d - %-*s     |\r\n", 0, TOOL_LIST_WIDTH - 11, "Now");
    for (int i = TIME_RANGE_LAST_1_HOUR; i <= TIME_RANGE_LAST_24_HOURS; i++) {
        printf("| %d - Past %d hour%-*s     |\r\n", i, i, TOOL_LIST_WIDTH - 18 - (i >= 10 ? 1 : 0), (i > 1 ? "s" : ""));
    }
    PrintLine(TOOL_LIST_WIDTH);
    printf("\n");
    printf("Enter time range number: ");
    fflush(stdout);
}

// 获取时间范围
static TimeRange GetTimeRange() {
    while (1) {
        PrintTimeRanges();
        int choice = SafeReadInt(TIME_RANGE_LAST_24_HOURS);
        return (TimeRange)choice;
    }
}

// 打印时间范围选项
static void PrintCustomTimeOptions() {
    PrintTooLName("Select time input method");
    printf("| %d - %-*s     |\r\n", 1, TOOL_LIST_WIDTH - 11, "Use predefined time ranges");
    printf("| %d - %-*s     |\r\n", 2, TOOL_LIST_WIDTH - 11, "Enter custom date and time");
    printf("| %d - %-*s     |\r\n", 0, TOOL_LIST_WIDTH - 11, "Back to main menu");
    PrintLine(TOOL_LIST_WIDTH);
    printf("\n");
    printf("Enter your choice: ");
}

// 打印日期时间输入提示
static void PrintDateTimeInputPrompt() {
    printf("\nPlease enter date and time in the following format:\n");
    printf("Example: %s represents %s\n", TIME_FORMAT_EXAMPLE, TIME_FORMAT_EXAMPLE);
    printf("Note: Time values must be in valid ranges (Month: %d-%d, Day: %d-%d, Hour: %d-%d, Minute: %d-%d, Second: %d-%d)\n",
           MIN_MONTH, MAX_MONTH, MIN_DAY, MAX_DAY, MIN_HOUR, MAX_HOUR, MIN_MINUTE, MAX_MINUTE, MIN_SECOND, MAX_SECOND);
}

// 获取自定义时间戳 - 一次性输入完整日期时间
static time_t GetCustomTimestamp(const char *prompt) {
    struct tm time_info = {0};
    int year, month, day, hour, minute, second;
    char input[128];
    char full_prompt[256];
    
    PrintDateTimeInputPrompt();
    
    // 构建提示信息
    snprintf(full_prompt, sizeof(full_prompt), "%s (YYYY-MM-DD HH:MM:SS): ", prompt);
    
    // 循环直到获取有效输入
    while (1) {
        printf("%s", full_prompt);
        fflush(stdout);
        if (fgets(input, sizeof(input), stdin) == NULL) {
            printf("Error reading input. Using current time.\n");
            return time(NULL);
        }
        
        // 解析输入的日期时间
        int parsed = sscanf(input, TIME_FORMAT_STRING, 
                           &year, &month, &day, &hour, &minute, &second);
        
        // 检查是否成功解析了所有6个字段
        if (parsed != 6) {
            printf("Invalid format. Please use YYYY-MM-DD HH:MM:SS format.\n");
            continue;
        }
        
        // 验证日期时间值的有效性
        if (year < MIN_YEAR || year > MAX_YEAR) {
            printf("Invalid year (%d). Year must be between %d and %d.\n", year, MIN_YEAR, MAX_YEAR);
            continue;
        }
        
        if (month < MIN_MONTH || month > MAX_MONTH) {
            printf("Invalid month (%d). Month must be between %d and %d.\n", month, MIN_MONTH, MAX_MONTH);
            continue;
        }
        
        if (day < MIN_DAY || day > MAX_DAY) {
            printf("Invalid day (%d). Day must be between %d and %d.\n", day, MIN_DAY, MAX_DAY);
            continue;
        }
        
        if (hour < MIN_HOUR || hour > MAX_HOUR) {
            printf("Invalid hour (%d). Hour must be between %d and %d.\n", hour, MIN_HOUR, MAX_HOUR);
            continue;
        }
        
        if (minute < MIN_MINUTE || minute > MAX_MINUTE) {
            printf("Invalid minute (%d). Minute must be between %d and %d.\n", minute, MIN_MINUTE, MAX_MINUTE);
            continue;
        }
        
        if (second < MIN_SECOND || second > MAX_SECOND) {
            printf("Invalid second (%d). Second must be between %d and %d.\n", second, MIN_SECOND, MAX_SECOND);
            continue;
        }
        
        // 填充time_info结构体
        time_info.tm_year = year - MIN_YEAR;
        time_info.tm_mon = month - 1;
        time_info.tm_mday = day;
        time_info.tm_hour = hour;
        time_info.tm_min = minute;
        time_info.tm_sec = second;
        time_info.tm_isdst = -1; // 让系统自动判断夏令时
        
        // 转换为时间戳
        time_t result = mktime(&time_info);
        if (result == -1) {
            printf("Failed to convert to timestamp. Using current time.\n");
            return time(NULL);
        }
        
        return result;
    }
}

// 将TimeRange转换为相对于指定时间的秒数
static time_t TimeRangeToSeconds(TimeRange timeRange, time_t baseTime) {
    switch (timeRange) {
        case TIME_RANGE_NOW:
            return baseTime;
        case TIME_RANGE_LAST_1_HOUR:
            return baseTime - 1 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_2_HOURS:
            return baseTime - 2 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_3_HOURS:
            return baseTime - 3 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_4_HOURS:
            return baseTime - 4 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_5_HOURS:
            return baseTime - 5 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_6_HOURS:
            return baseTime - 6 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_7_HOURS:
            return baseTime - 7 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_8_HOURS:
            return baseTime - 8 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_9_HOURS:
            return baseTime - 9 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_10_HOURS:
            return baseTime - 10 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_11_HOURS:
            return baseTime - 11 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_12_HOURS:
            return baseTime - 12 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_13_HOURS:
            return baseTime - 13 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_14_HOURS:
            return baseTime - 14 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_15_HOURS:
            return baseTime - 15 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_16_HOURS:
            return baseTime - 16 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_17_HOURS:
            return baseTime - 17 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_18_HOURS:
            return baseTime - 18 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_19_HOURS:
            return baseTime - 19 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_20_HOURS:
            return baseTime - 20 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_21_HOURS:
            return baseTime - 21 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_22_HOURS:
            return baseTime - 22 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_23_HOURS:
            return baseTime - 23 * SECONDS_PER_HOUR;
        case TIME_RANGE_LAST_24_HOURS:
            return baseTime - HOURS_PER_DAY * SECONDS_PER_HOUR;
        default:
            return baseTime;
    }
}

// 提取公共查询规则设置函数
static void SetupQueryRule(CommTraffQueryRule *queryRule) {
    while (1) {
        PrintTraffTypesForQuery();
        int traff_type = SafeReadInt(sizeof(traffic_type_names) / sizeof(traffic_type_names[0]));
        if (traff_type == 0) {
            // 用户选择返回主菜单，将traffType设置为无效值
            queryRule->traffType = (TraffType)-1;
            return;
        }

        queryRule->traffType = (TraffType)(traff_type - 1);

        // 询问用户如何输入时间范围
        int time_choice;
        do {
            PrintCustomTimeOptions();
            time_choice = SafeReadInt(2);
            if (time_choice == 0) {
                // 用户选择返回主菜单
                queryRule->traffType = (TraffType)-1;
                return;
            } else if (time_choice == 1) {
                // 使用预定义时间范围
                printf("Select start time range:\n");
                TimeRange startTimeRange = GetTimeRange();
                printf("Select end time range:\n");
                TimeRange endTimeRange = GetTimeRange();
                
                // 将TimeRange转换为time_t
                time_t now = time(NULL);
                queryRule->startTime = TimeRangeToSeconds(startTimeRange, now);
                queryRule->endTime = TimeRangeToSeconds(endTimeRange, now);
                break;
            } else if (time_choice == 2) {
                // 输入自定义日期时间
                queryRule->startTime = GetCustomTimestamp("Start time");
                queryRule->endTime = GetCustomTimestamp("End time");
                break;
            } else {
                printf("Invalid choice! Please try again.\n");
            }
        } while (1);
        
        // 验证时间范围的有效性
        if (queryRule->startTime > queryRule->endTime) {
            printf("Warning: Start time is later than end time. Swapping values.\n");
            time_t temp = queryRule->startTime;
            queryRule->startTime = queryRule->endTime;
            queryRule->endTime = temp;
        }
        
        printf("Query time range set:\n");
        printf("  Start time: %s", ctime(&queryRule->startTime));
        printf("  End time: %s", ctime(&queryRule->endTime));
        
        break;
    }
}

// 查询通信流量记录
static void QueryCommTraffRecords() {
    CommTraffQueryRule queryRule = {0};
    SetupQueryRule(&queryRule);
    // 检查用户是否选择返回主菜单
    if (queryRule.traffType < 0) {
        return;
    }

    CommTraffQueryCb cb = {0};
    cb.OnQuery = OnQuery;
    cb.OnComplete = OnComplete;

    int32_t result = QueryCommTraff(&queryRule, &cb);
    if (result != COMMTRAFF_SUCCESS) {
        printf("Query failed with error code: %d\n", result);
    }
}

// 查询通信流量数量
static void CommTraffNumsQuery() {
    printf("-----------------------------------------\n");
    printf("query commtraff nums no implement\n");
    printf("-----------------------------------------\n");
}

// 改进的安全输入读取函数，支持字符输入
static int SafeReadChoice(int max) {
    char input[128];
    char *endptr;
    long value;
    
    while (1) {
        if (fgets(input, sizeof(input), stdin) == NULL) {
            printf("Error reading input. Please try again.\n");
            continue;
        }
        
        // 检查是否是帮助命令
        if (input[0] == 'h' || input[0] == 'H') {
            PrintCategoryHelp();
            return -1; // 特殊返回值表示显示了帮助
        }
        
        value = strtol(input, &endptr, 10);
        if (*endptr == '\n' || *endptr == '\0') {
            if (value >= 0 && value <= max) {
                return (int)value;
            }
        }
        printf("Invalid input! Please enter a number between 0 and %d, or 'h' for help.\n", max);
    }
}

int32_t main() {
    // 初始化随机数种子，支持随机间隔功能
    srand(time(NULL));
    if (CommtraffInit() != COMMTRAFF_SUCCESS) {
        printf("Failed to initialize CommTraff\n");
        return -1;
    }
    while (1) {
        PrintMenu();

        int choice = SafeReadChoice(g_mainMenuNum - 1);  // 最大选项数(不包括Exit)
        if (choice == -1) {
            continue; // 显示了帮助，重新显示菜单
        } else if (choice == 0) {
            printf("Exiting...\n");
            break;
        } else if (choice >= 1 && choice < g_mainMenuNum) {
            // 调用对应的函数
            if (g_mainMenuList[choice - 1].func != NULL) {
                g_mainMenuList[choice - 1].func();
            }
        } else {
            printf("Invalid choice! Please select from the available options.\n");
        }
    }
    CommtraffDeinit();
    return 0;
}
